home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / rs0422.zip / CONFIGUR / CONFIG.C < prev    next >
C/C++ Source or Header  |  1990-10-26  |  14KB  |  532 lines

  1. /*
  2.  * Copyright 1988 by the Radio Amateur Telecommunications Society
  3.  * and Thomas A. Moulton, W2VY
  4.  *
  5.  * This software may only be modified, copied, distributed or
  6.  * executed for non-profit purposes by individuals operating
  7.  * systems in the Amateur Radio Service.  Credit to the
  8.  * author(s) and to the Radio Amateur Telecommunications Society
  9.  * must be made in modules where RATS provided software is used,
  10.  * and in any announcements and documentation.  
  11.  *
  12.  * As a non-profit, research and development organization,  the
  13.  * Radio Amateur Telecommunications Society distributes software
  14.  * in both executable and source forms.  This policy is in place
  15.  * to encourage the development and distribution of OSI-based,
  16.  * networking tools.  In order to protect the interests of the
  17.  * Society and the authors, we have placed some conditions
  18.  * of use on the software.  Other groups are encouraged
  19.  * to place the same or similar guidelines on
  20.  * software they produce.
  21.  *
  22.  * The Radio Amateur Telecommunications Society reserves the right
  23.  * to specify and alter the terms under which software provided by
  24.  * the Society may be used.  This policy is consistent with the 
  25.  * objective of uniform and consistent "Open Systems Interconnections."
  26.  * 
  27.  * All acceptable Amateur Radio related uses of this software
  28.  * will be outlined in the "ROSE Implementer's Guide".  Individuals
  29.  * or organizations wishing to add to, or modify the provisions of
  30.  * the guide to accommodate local or evolutionary requirements
  31.  * should document the proposed change(s) and forward them to the
  32.  * Society.  If accepted, written notification will be provided by
  33.  * the Society to the submitting organization or individual(s).
  34.  * The Society will then issue a "ROSE Implementer's Guide Change
  35.  * Notice".  Periodically, the Society will re-issue the "ROSE 
  36.  * Implementer's Guide" and incorporate the text of the change 
  37.  * notices.  This procedure has been put in to place to ensure
  38.  * compatibility between systems and to ensure their "Openness"
  39.  * and interoperability.
  40.  *
  41.  * No part of this software may be used in other packages 
  42.  * without prior authorization from the author or the Society.  
  43.  * Software incorporating this module, all or in part, must be 
  44.  * provided to the Society prior to distribution or use by
  45.  * anyone not directly involved in testing of the revised  
  46.  * environment.  Current releases of the combined software must
  47.  * be provided to the Society in both source and executable
  48.  * forms.  Adequate documention to produce an executable module 
  49.  * from the provided source must also be included.
  50.  *
  51.  * Non-Amateur Radio non-profit uses may be authorized on a case
  52.  * by case basis.  Inquiries for such use may be made in writing
  53.  * to the Society. Non-commercial uses consistent with the
  54.  * general principles of Open Systems Interconnection Reference
  55.  * Model will be generally considered with favor.
  56.  *
  57.  * Commercial licensing of the software is also available based
  58.  * on normal commercial terms.  Licensing inquiries should be
  59.  * directed to the Society.  Commercial licensing of the standard
  60.  * software will be done in situations which materially benefit
  61.  * the Amateur Radio Packet Network.  Additional licensing is
  62.  * reserved by the individual authors.
  63.  * 
  64.  * The Radio Amateur Telecommunications Society provides this software
  65.  * on an "as is" basis.  The Society assumes no liability for
  66.  * loss incurred through the use of this software.  Amateur Radio
  67.  * use of this software implies non-commercial and voluntary 
  68.  * development, deployment and use of this software in a "Amateur",
  69.  * non-commercial service.  Commercial users are encouraged to
  70.  * inspect their copies of the source code.  Source code modification
  71.  * licenses are available if a combined Object and Source Code
  72.  * license was not originally established.
  73.  * 
  74.  * The Society may be contacted by writing or calling at:
  75.  * 
  76.  * The Radio Amateur Telecommunications Society 
  77.  * 206 North Vivyen Street.
  78.  * Bergenfield, New Jersey 07621
  79.  *
  80.  * Telephone: 201-387-8896
  81.  *
  82.  */
  83. #include "data.h"
  84. #include "buffer.h"
  85. #include "iface.h"
  86. #include "timer.h"
  87. #include "ax25.h"
  88. #include "ax25l2.h"
  89. #include "l3struc.h"
  90. #include "x25cause.h"
  91. #include "l3calls.h"
  92. #include "tx.h"
  93. #include "config.h"
  94. #include "upfcn.h"
  95.  
  96. int NULLFCN(), clr_config(), con_config(), recv_boot();
  97. int send_config(), rst_boot(), unload_ok();
  98.  
  99. struct upfcn config={
  100.     {{0x86, 0x9e, 0x9c, 0x8c, 0x92, 0x8e}, {0x00}}, /* CONFIG-0 */
  101.     rst_boot, clr_config, con_config, recv_boot,
  102.     send_config, NULLFCN, unload_ok,
  103.     "CONFIG - ROSE X.25 Packet Switch Configuration Interface Ver 2.3\r"
  104. };
  105.  
  106. extern unsigned char node_addr[];
  107. extern int userport;
  108. extern struct ax25_parms *l2parms, *l3parms;
  109. extern struct datastr *l2_user_info, l2_info;
  110.  
  111. extern unsigned char NPAroute[][16];
  112. extern unsigned char RTable[];
  113.  
  114. extern unsigned char passlen;
  115.  
  116. #define cnf_clrdta() free_stuff(&save_cnf_data)
  117.  
  118. struct datastr *mkpkt();
  119. int check_x121();
  120. unsigned char *malloc(), *calloc();
  121. void free();
  122.  
  123. int bss_i(), usr_info(), rt_init(), examod_i();
  124. int buf();
  125.  
  126. #define READONLY 0x80
  127. #define MUSTCLEAR 0x40
  128. #define RESET 0x20
  129. #define DYNAMIC 0x10
  130. #define BAD_OBJ 0x08
  131. #define FCNCALL 0x01
  132.  
  133.   /* MUSTCLEAR says to update this we need to clear all links */
  134.   /* RESET says we can reset this after a read */
  135.   /* DYNAMIC says the Object is a pointer pointing to malloc'ed memory */
  136.   /* BAD_OBJ Says the object is not supported */
  137.   /* FCNCALL says to call *fcn() to copy byte */
  138.  
  139. struct inftab {
  140.     void *obj;        /* Pointer to the object we are working with */
  141.     int len;        /* It's length (number of items) */
  142.     int size;        /* it's size (bytes/item) */
  143.     char flags;        /* Special handling flags */
  144.     int (*init)();        /* Set up vars for get/put */
  145.     int (*fcn)();        /* Function to handle one byte */
  146. };
  147. struct inftab inf[MAXOBJ] = {
  148.         {&l2_user_info,1,0,DYNAMIC+FCNCALL,usr_info,buf},
  149.         {L3CALL,L3SIZ,AXALEN,0,bss_i,NULL},
  150.         {L3DIGI,L3SIZ,AXALEN,0,bss_i,NULL},
  151.         {L3PORT,L3SIZ,1,0,bss_i,NULL},
  152.         {L3_MAXVC,L3SIZ,1,0,bss_i,NULL},
  153.         {L3_WI,L3SIZ,1,0,bss_i,NULL},
  154.         {L3DELAY,16,2,0,bss_i,NULL},
  155.         {&userport,1,sizeof(int),0,bss_i,NULL},
  156.         {node_addr,1,7,0,bss_i,NULL},
  157.         {&l2parms,1,sizeof(struct ax25_parms),DYNAMIC,bss_i,NULL},
  158.         {&l3parms,1,sizeof(struct ax25_parms),DYNAMIC,bss_i,NULL},
  159.         {NPAroute,1,16*16,0,bss_i,NULL},
  160.         {RTable,1,2048,0,bss_i,NULL},
  161.         {&passlen,1,257,0,bss_i,NULL},
  162.         {NULL,1,0,READONLY,bss_i,NULL},
  163.         {NULL,0,1,DYNAMIC,examod_i,NULL}
  164.     };
  165.  
  166. #define WRITE 01
  167. #define READ 02
  168. #define READR 03
  169. #define MAXCMD 03
  170.  
  171. #if 0
  172. char *errmsg[]={
  173.     "Invalid command\n",
  174.     "Invalid Object specified\n",
  175.     "No working memory!\n",
  176.     "Bad checksum!\n",
  177.     "Not implemented yet, sorry\n"
  178.     "Odd number of data bytes for type\n"
  179.     "Item is Read-Only"
  180. };
  181. #endif
  182.  
  183. char cnf_busy;
  184. char cnf_state;
  185. struct datastr *cnf_in;
  186. char cnf_cmd;
  187. char cnf_obj;
  188. int cnf_len;
  189. int cnf_pos;
  190. unsigned char *cnf_data, *save_cnf_data;
  191. unsigned char cnf_checksum;
  192. char cnf_high;
  193. unsigned char cnf_chv;
  194.  
  195. #if 0
  196. int
  197. hexch(ch)
  198. unsigned char ch;
  199. {
  200.     if (ch>0x39) ch -= 7;
  201.     if (ch<0x30 || ch>0x3f) return -1;
  202.     return (ch-0x30);
  203. }
  204.  
  205. int
  206. xch(val)
  207. unsigned char val;
  208. {
  209.     val = (val & 0x0f);
  210.     if (val > 9) val += 7;
  211.     return (val + 0x30);
  212. }
  213.  
  214. putxch(p,val)
  215. register struct datastr *p;
  216. int val;
  217. {
  218.     bappch(p,xch(val >> 4));
  219.     bappch(p,xch(val));
  220. }
  221.  
  222. putxint(p,val)
  223. register struct datastr *p;
  224. int val;
  225. {
  226.     putxch(p,val);        /* Low byte Low address */
  227.     putxch(p,(val>>8));
  228. }
  229. #endif
  230.  
  231. int
  232. con_config(vc)
  233. register struct VCS *vc;
  234. {
  235.  
  236.     vc=vc->peer;
  237.     if (!vc) return;
  238.     puthex2("con",vc,"at",fn);
  239.     send_l3(vc,info_pkt());
  240.     if (cnf_busy) vc_clear(vc->peer,Number_Busy);
  241.     else {
  242.         cnf_busy = 1;
  243.         cnf_state = 1;
  244.     }
  245. }
  246.  
  247. int
  248. clr_config(vc,c)
  249. struct VCS *vc;
  250. int c;
  251. {
  252.     cnf_busy = 0;
  253. /*    cnf_clrdta(); Not sure if we should do this */
  254.     set_p(vc, P1, 0);
  255. }
  256.  
  257. int
  258. send_config(vc, pkt)
  259. register struct VCS *vc;
  260. struct datastr *pkt;
  261. {
  262.     static int i, ch;
  263.     int hexch();
  264.  
  265.     puthex2("send fig",vc,"",pkt);
  266.     vc_queue_data(vc,pkt);
  267.     while ((cnf_in = vc->tx_queue)) /* There is stuff waiting */ {
  268.         vc->tx_queue=cnf_in->next;
  269.         cnf_in->next=NULL;
  270.         while ((ch=bgetch(&cnf_in)) != EOF) {
  271.             puthex2("loop",ch,"",cnf_in);
  272.             if (ch > 0x20) /* Allow Control chars to pass */ {
  273.                 i=hexch(ch);
  274.                 if (ch == 0x3a || i<0 ) cnf_state=1;
  275.                 if (cnf_state == 1) /* Clean Up */ {
  276.                     cnf_clrdta();
  277.                     cnf_data = NULL;
  278.                     cnf_chv = ch;
  279.                     cnf_high = TRUE;
  280.                 } else {
  281.                     if (cnf_high) cnf_chv = i<<4;
  282.                     else cnf_chv += i;
  283.                     cnf_high = !cnf_high;
  284.                 }
  285.                 if (cnf_high) cnf_next(vc, cnf_chv);
  286.             }
  287.         }
  288.     }
  289.     return 256;    /* We are never busy! */
  290. }
  291.  
  292. /* cnf_state has the following meaning 
  293. /*    1 - Searching for a : (Start of record)
  294. /*    2 - Next byte read is the command
  295. /*    3 - Next byte read is the object we are working with
  296. /*    4 - Next byte read is the low byte of length !Low byte Low address!
  297. /*    5 - Next byte read is the high byte of length
  298. /*    6 - Next byte read is additional data
  299. /*    7 - Processing request
  300. */
  301.  
  302. cnf_next(vc,chv)
  303. struct VCS *vc;
  304. unsigned char chv;
  305. {
  306.     static char err;
  307.     static int len;
  308.     register struct VCS *vcp;
  309.     static struct inftab *rec;
  310.     int do_config();
  311.  
  312.     err=0;
  313.     vcp=vc->peer;
  314.     puthex2("next",cnf_state,"ch",chv);
  315.     switch (cnf_state) {
  316.         case 1: if (chv != 0x3a) cnf_state=0;
  317.             break;
  318.         case 2: cnf_cmd=chv;
  319.             if (chv>MAXCMD) err=1;
  320.             break;
  321.         case 3: cnf_obj=chv;
  322.             if (chv>MAXOBJ) err=2;
  323.             else if (inf[cnf_obj].flags & BAD_OBJ) err=2;
  324.             break;
  325.         case 4: cnf_len= chv;    /* Low byte Low address */
  326.             break;
  327.         case 5: cnf_len += (chv<<8);
  328.             cnf_pos=0;
  329.             cnf_checksum=0;
  330.             rec = &inf[cnf_obj];
  331.             len= rec->size * rec->len;
  332.             if (rec->flags & DYNAMIC) len=cnf_len;
  333.             if (len) /* && cnf_cmd == WRITE) */ {
  334.                 cnf_data=save_cnf_data=calloc(1,len);
  335.                 if (cnf_data == NULL) err=3;
  336.             }
  337.             if (cnf_len == 0) cnf_state++; /* No data field */
  338.             break;
  339.         case 6: cnf_data[cnf_pos]=chv;
  340.             cnf_pos++;
  341.             cnf_checksum += chv;
  342.             if (cnf_pos != cnf_len) cnf_state--;
  343.             break;
  344.         case 7: cnf_checksum += chv;
  345.             if (cnf_checksum != 0) err=4;
  346.             else err=do_config(vcp);
  347.             if (!err) send_l3(vcp,mkpkt("OK\r"));
  348.             cnf_clrdta();
  349.             cnf_state=0;
  350.             break;
  351.     }
  352.     if (err) {
  353.         if (vcp) send_l3(vcp, l_message(" Error ", err));
  354.         cnf_state=0;
  355.     }
  356.     cnf_state++;
  357.     puthex2("exit",cnf_state,"err",err);
  358. }
  359.  
  360. int
  361. do_config(vc)
  362. struct VCS *vc;
  363. {
  364.     static int j, len;
  365.     static struct datastr *bp;
  366.     register struct inftab *rec;
  367.     static unsigned char *ch, *ch1;
  368.  
  369.     puthex2("do it",cnf_cmd,"",cnf_obj);
  370.     rec = &inf[cnf_obj];
  371.     len = (*rec->init)(rec, &ch);
  372.     if (len < 0) return -len;
  373.     if (cnf_cmd == WRITE) {
  374.         if (rec->flags & READONLY) return 7;
  375.         ch1 = (unsigned char *)cnf_data;
  376.         while (len>0) {
  377.             len--;
  378.             if (rec->flags & FCNCALL) {
  379.                 (*rec->fcn) (&ch, &ch1, len);
  380.                 ch1++;
  381.             }
  382.             else *ch++ = *ch1++;
  383.         }
  384.         sumchk();    /* Reset the checksum for bbRAM */
  385.     }
  386.     else if (cnf_cmd == READ) {
  387.         bp=new_buffer((len*2)+10);
  388.         if (!bp) return 3;
  389.         bappch(bp,0x3a);
  390.         putxch(bp,cnf_obj);    /* Identify what we are sending */
  391.         putxint(bp,len);        /* and how big it is */
  392.         cnf_checksum=0;
  393.         while (len > 0) {
  394.             len--;
  395.             if (rec->flags & FCNCALL)
  396.                 j = (*rec->fcn)(&ch, NULL, len);
  397.             else j = *ch++;
  398.             cnf_checksum += j;
  399.             putxch(bp,j);
  400.         }
  401.         putxch(bp,-cnf_checksum);
  402.         bappch(bp,0x0d);
  403.         send_l3(vc,bp);
  404.     }
  405.     else return 5;
  406.     return 0;
  407. }
  408.  
  409. usr_info(rec,ch)
  410. struct inftab *rec;
  411. struct datastr **ch;
  412. {
  413.     register struct datastr *bp;
  414.     static int len;
  415.  
  416.     if (cnf_cmd == WRITE) {
  417.         if (l2_user_info != &l2_info) free_pkt(l2_user_info);
  418.         l2_user_info=dup_pkt(&l2_info);
  419.         len = cnf_len;
  420.         bp=new_buffer(len);
  421.         if (!bp) return -1;
  422.         l2_user_info=binsert(l2_user_info,bp);
  423.     }
  424.     else /* It's Read (or ReadR) */ {
  425.         bp=dup_pkt(l2_user_info); /* Leave orig. alone */
  426.         if (!bp) len = -1;
  427.         else len = buflen(bp);
  428.     }
  429.     *ch = bp;
  430.     return len;
  431. }
  432.  
  433. int
  434. buf(bpx,ch,left)
  435. struct datastr **bpx;
  436. unsigned char **ch;
  437. int left;    /* Number of bytes (aka calls) left */
  438. {
  439.     static int c;
  440.  
  441.     if (cnf_cmd == WRITE) bappch(*bpx,**ch);
  442.     else /* Read */ {
  443.         if (*bpx == NULL) return EOF;
  444.         c=bgetch(bpx);
  445.         if (!left) free_stuff(bpx);
  446.         return c;
  447.     }
  448. }
  449.  
  450. int
  451. bss_i(rec,ch)
  452. register struct inftab *rec;
  453. unsigned char **ch;
  454. {
  455.     static unsigned char *ch1;
  456.  
  457.     ch1 = (unsigned char *)rec->obj;
  458.     if (rec->flags & DYNAMIC) ch1 = *(unsigned char **)ch1;
  459.     *ch = ch1;
  460.     return (rec->size * rec->len);
  461. }
  462.  
  463. #if 0
  464. int
  465. rt_init(rec,ch)
  466. struct inftab *rec;
  467. unsigned char **ch;
  468. {
  469.     static int i, j, k, l, nd, c;
  470.     static struct dnic dn;
  471.  
  472.     for (i=0;i<3;i++) {
  473.         if (cnf_len <= 0) return -6;
  474.         cnf_len--;
  475.         c = *cnf_data++;
  476.         dn.adr[i] = c;
  477.     }
  478.     for (i=0;i<ndnics;i++) {
  479.         if (check_x121(DNics[i].adr,dn.adr) >= 0) break;
  480.     }
  481.     if (cnf_cmd == WRITE) {
  482.         *ch = NULL;    /* Invalid DNIC */
  483.         if (i<ndnics) free_stuff(&DNics[i].rt);
  484.         l = cnf_len;
  485.         if (cnf_len == 0) /* Delete DNIC */ {
  486.             if (i == ndnics) return 0; /* Deleted Invalid DNIC */
  487.             nd = ndnics-1;
  488.             if (i == nd) ndnics--;
  489.             else /* Have to copy rest... */ {
  490.                 for (j=i;j<nd;j++) {
  491.                     for (k=0;k<3;k++)
  492.                        DNics[j].adr[k] = DNics[j+1].adr[k];
  493.                     DNics[j].rt = DNics[j+1].rt;
  494.                 }
  495.             }
  496.         }
  497.         else /* Add Dnic */ {
  498.             if (i == ndnics) {
  499.                 ndnics++;
  500.                 for (j=0;j<3;j++) DNics[i].adr[j] = dn.adr[j];
  501.             }
  502.             else free_stuff(&DNics[i].rt);
  503.             DNics[i].rt = *ch = malloc(cnf_len);
  504.             DNics[i].len = cnf_len;
  505.         }
  506.     }
  507.     else /* READ */ {
  508.         if (i == ndnics) return -2;    /* Invalid DNIC */
  509.         *ch = DNics[i].rt;
  510.         l = DNics[i].len;
  511.     }
  512.     return l;
  513. }
  514. #endif
  515.  
  516. int
  517. examod_i(rec,ch)
  518. struct inftab *rec;
  519. unsigned char **ch;
  520. {
  521.     static int len;
  522.     register unsigned int *dta;
  523.  
  524.     if (cnf_len < 4) return -6;
  525.     dta = (unsigned int *) cnf_data;
  526.     *ch = (unsigned char *) *dta;
  527.     len = *(dta+1);
  528.     cnf_data += 4;
  529.     cnf_len -= 4;
  530.     return len;
  531. }
  532.